package com.gun.management.module.raffle.dal.mysql.lotterylog;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.gun.management.framework.common.pojo.PageResult;
import com.gun.management.framework.mybatis.core.mapper.BaseMapperX;
import com.gun.management.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.gun.management.module.raffle.controller.admin.lotterylog.vo.LotteryLogPageReqVO;
import com.gun.management.module.raffle.controller.admin.lotterylog.vo.LotteryLogRespVO;
import com.gun.management.module.raffle.controller.app.vo.*;
import com.gun.management.module.raffle.dal.dataobject.lottery.LotteryDO;
import com.gun.management.module.raffle.dal.dataobject.lotterylog.LotteryLogDO;
import com.gun.management.module.raffle.dal.dataobject.lotteryrule.LotteryRuleDO;
import com.gun.management.module.raffle.dal.dataobject.lotteryruleref.LotteryRuleRefDO;
import com.gun.management.module.system.dal.dataobject.user.AdminUserDO;
import org.apache.ibatis.annotations.*;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户抽奖日志 Mapper
 *
 * @author 测试账号
 */
@Mapper
public interface LotteryLogMapper extends BaseMapperX<LotteryLogDO> {

    @Insert("INSERT INTO `by_mall_pro`.`raffle_lottery_log` (  `user_id`, `lottery_id`, `rule_id`, `total_times`, " +
            "`day_total_times`, `expense_score`, `status`, `order_no`, `lottery_time`,   `creator`," +
            " `create_time`, `updater`, `update_time`,  `ext_json`) " +
            " VALUES ( #{entity.userId}, #{entity.lotteryId}, #{entity.ruleId}, #{entity.totalTimes}, #{entity.dayTotalTimes}" +
            ", #{entity.expenseScore},  #{entity.status},  #{entity.orderNo},#{entity.lotteryTime},  #{entity.creator},  " +
            "#{entity.createTime}, #{entity.updater},  #{entity.updateTime}, #{entity.extJson});  ")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    public void insertAndGetId(@Param("entity") LotteryLogDO entity);

    default PageResult<LotteryLogDO> selectPage(LotteryLogPageReqVO reqVO) {
        List<Long> lotteryRuleList = new ArrayList<Long>();
        List<Long> lotteryList = new ArrayList<Long>();
        List<Long> userList = new ArrayList<Long>();
        LambdaQueryWrapperX<LotteryLogDO> lambdaQueryWrapperX = new LambdaQueryWrapperX<LotteryLogDO>();
        lambdaQueryWrapperX.betweenIfPresent(LotteryLogDO::getLotteryTime, reqVO.getLotteryTime())
                .orderByAsc(LotteryLogDO::getLotteryTime);

        if (reqVO.getNickName() != null) {
            MPJLambdaWrapper<LotteryLogDO> mpjLambdaWrapper2 = new MPJLambdaWrapper();
            mpjLambdaWrapper2
                    .select(LotteryLogDO::getUserId)
                    .innerJoin(AdminUserDO.class, AdminUserDO::getId, LotteryLogDO::getUserId)
                    .innerJoin(AdminUserDO.class, AdminUserDO::getTenantId, LotteryLogDO::getTenantId)
                    .like(AdminUserDO::getNickname, reqVO.getNickName());

            userList = this.selectJoinList(LotteryLogDO.class, mpjLambdaWrapper2).stream().map(LotteryLogDO::getUserId).distinct().collect(Collectors.toList());
            lambdaQueryWrapperX.inIfPresent(LotteryLogDO::getUserId, userList);

        }

        if (reqVO.getLotteryCategoryId() != null) {
            MPJLambdaWrapper<LotteryLogDO> mpjLambdaWrapper2 = new MPJLambdaWrapper();


            mpjLambdaWrapper2
                    .select(LotteryLogDO::getLotteryId)
                    .innerJoin(LotteryDO.class, LotteryDO::getId, LotteryLogDO::getLotteryId)
                    .innerJoin(LotteryDO.class, LotteryDO::getTenantId, LotteryLogDO::getTenantId)
                    .eq(LotteryDO::getCategoryId, reqVO.getLotteryCategoryId());

            lotteryList = this.selectJoinList(LotteryLogDO.class, mpjLambdaWrapper2).stream().map(LotteryLogDO::getLotteryId).distinct().collect(Collectors.toList());

            lambdaQueryWrapperX.inIfPresent(LotteryLogDO::getLotteryId, lotteryList);
        }
        if (reqVO.getRuleCategoryId() != null) {

            MPJLambdaWrapper<LotteryLogDO> mpjLambdaWrapper1 = new MPJLambdaWrapper();
            mpjLambdaWrapper1
                    .select(LotteryLogDO::getRuleId)
                    .innerJoin(LotteryRuleDO.class, LotteryRuleDO::getId, LotteryLogDO::getRuleId)
                    .innerJoin(LotteryRuleDO.class, LotteryRuleDO::getTenantId, LotteryLogDO::getTenantId)
                    .eq(LotteryRuleDO::getCategoryId, reqVO.getRuleCategoryId());

            lotteryRuleList = this.selectJoinList(LotteryLogDO.class, mpjLambdaWrapper1).stream().map(LotteryLogDO::getRuleId).distinct().collect(Collectors.toList());
            ;

            lambdaQueryWrapperX.inIfPresent(LotteryLogDO::getRuleId, lotteryRuleList);


        }

        return selectPage(reqVO, lambdaQueryWrapperX);
    }


    default PageResult<LotteryLogDO> selectAllRecordListPage(Long userId,Long telantId,AppLotteryLogPageReqVO pageReqVO) {

        MPJLambdaWrapper<LotteryLogDO> mpjLambdaWrapper1 = new MPJLambdaWrapper();
        mpjLambdaWrapper1
                .selectAll(LotteryLogDO.class)
                .select(AdminUserDO::getMobile)
                .select(LotteryRuleDO::getName).setParamAlias("prizeName")
                .leftJoin(AdminUserDO.class, AdminUserDO::getId, LotteryLogDO::getUserId)
                .leftJoin(AdminUserDO.class, AdminUserDO::getTenantId, LotteryLogDO::getTenantId)
                .leftJoin(LotteryRuleDO.class, LotteryRuleDO::getId, LotteryLogDO::getRuleId)
                .leftJoin(LotteryRuleDO.class, LotteryRuleDO::getTenantId, LotteryLogDO::getTenantId);

        if (userId != null) {
            mpjLambdaWrapper1.eq(LotteryLogDO::getUserId, userId);
        }
        if (telantId != null) {
            mpjLambdaWrapper1.eq(LotteryLogDO::getTenantId, telantId);
        }

        mpjLambdaWrapper1.orderByDesc(LotteryLogDO::getLotteryTime);


        IPage<LotteryLogDO> mPage = this.selectJoinPage(new Page<LotteryLogDO>(pageReqVO.getPageNo(), pageReqVO.getPageSize()), LotteryLogDO.class, mpjLambdaWrapper1);

        return new PageResult(mPage.getRecords(), mPage.getTotal());
    }



    @Select({"<script>SELECT " +
            " A.id,  A.lottery_id," +
            "  C.category_id lotteryCategoryId, " +
            "   A.rule_id,A.user_id," +
            "  B.mobile original_mobile," +
            " C.`name` lotteryName," +
            " D.name lottery_rule_name,   " +
            " D.category_id prizeType, " +
            " B.nickname,CONCAT(LEFT(B.mobile, 3), '****', RIGHT(B.mobile, 4)) mobile, " +
            " A.expense_score, " +
            " A.status," +
            " (select label from system_dict_data S WHERE S.dict_type='prize_status' and S.value = A.status) statusName," +
            " A.lottery_time," +
            " A.update_time," +
            "  CASE  " +
            " WHEN (D.category_id = 0 or D.category_id = 99) THEN  " +
            " replace( " +
            " concat('收件人:', ifnull(JSON_EXTRACT(A.ext_json,'$.receiver') ,''),  '\n', " +
            " '电话:',if(isnull(JSON_EXTRACT(A.ext_json,'$.receiverPhone')) ,'', JSON_EXTRACT(A.ext_json,'$.receiverPhone')),'\n', " +
            " '收货地址:',if(isnull(JSON_EXTRACT(A.ext_json,'$.provinceName')) ,'',   JSON_EXTRACT(A.ext_json,'$.provinceName')), " +
            " if(isnull(JSON_EXTRACT(A.ext_json,'$.cityName')) ,'',  JSON_EXTRACT(A.ext_json,'$.cityName'))  , " +
            " if(isnull(JSON_EXTRACT(A.ext_json,'$.districtName')) ,'',  JSON_EXTRACT(A.ext_json,'$.districtName')) , " +
            " if(isnull(JSON_EXTRACT(A.ext_json,'$.streetName')) ,'', JSON_EXTRACT(A.ext_json,'$.streetName')), " +
            " if(isnull(JSON_EXTRACT(A.ext_json,'$.addressDetail')) ,'',   concat(JSON_EXTRACT(A.ext_json,'$.addressDetail'),''))),'\"','') " +
            " WHEN D.category_id = 3  THEN   replace(concat('直充账号:',ifnull(JSON_EXTRACT(A.ext_json,'$.rechargeAccount'),'')),'\"','')  " +
            " WHEN D.category_id = 6 THEN  replace(concat('卡密:',ifnull(JSON_EXTRACT(A.ext_json,'$.goodsCardPwd'),''), '\n'," +
            "    '有效期:',ifnull(JSON_EXTRACT(A.ext_json,'$.goodsCardExpire'),''),''),'\"','') " +
            " ELSE '无' "  +
            " END ext_json_info,A.order_no  " +
            "FROM " +
            " raffle_lottery_log A " +
            " LEFT JOIN member_user B ON A.user_id = B.id  " +
            " AND A.tenant_id = B.tenant_id " +
            " LEFT JOIN raffle_lottery C on A.lottery_id = C.id  " +
            " AND A.tenant_id = C.tenant_id " +
            " LEFT JOIN raffle_lottery_rule D ON A.rule_id = D.id  " +
            " AND A.tenant_id = D.tenant_id  " +
            "<where>" +
            "<if test='lotteryCategoryId != null  '>" +
            " and C.category_id =  #{lotteryCategoryId}  " +
            "</if>" +
            "<if test='nickName != null and nickName != \"\"'>" +
            " and B.nickname like concat('%',#{nickName},'%')" +
            "</if>" +

            "<if test='lotteryName != null and lotteryName != \"\"'>" +
            " and  C.`name`  like concat('%',#{lotteryName},'%')" +
            "</if>" +

            "<if test='prizeName != null and prizeName != \"\"'>" +
            " and  D.`name`  like concat('%',#{prizeName},'%')" +
            "</if>" +

            "<if test='orderNo != null and orderNo != \"\"'>" +
            " and  A.order_no  like concat('%',#{orderNo},'%')" +
            "</if>" +
            "<if test='prizeStatus != null '>" +
                    " and A.status =  #{prizeStatus}  " +
            "</if>" +
            "<if test='prizeCategoryId != null '>" +
            " and D.category_id =  #{prizeCategoryId}  " +
            "</if>" +
            "<if test='lotteryTime != null '>" +
            " and A.lottery_time  between  #{lotteryTime[0]} and #{lotteryTime[1]}  " +
            "</if>" +
            "</where>" +
            " order by A.lottery_time desc,A.id desc " +
            "</script>"}
    )
    public IPage<LotteryLogRespVO> getAdminLotteryLogPageList(IPage<?> page, @Param("lotteryCategoryId") Long  lotteryCategoryId , @Param("nickName") String nickName, @Param("prizeCategoryId") Long  prizeCategoryId , @Param("lotteryTime") LocalDateTime[] lotteryTime,@Param("lotteryName") String lotteryName,@Param("prizeName") String prizeName,@Param("orderNo") String orderNo,@Param("prizeStatus") Integer prizeStatus);



    @Select({"<script>SELECT " +
            " A.id, " +
            " D.name prize_name,   " +
            " A.lottery_time,  A.user_id," +
            " B.nickname nick_name, " +
            " G.sku," +
            " D.avatar," +
            " D.category_id," +
            " ( SELECT S.label FROM system_dict_data S WHERE S.dict_type = 'su_goods_type' AND VALUE = D.category_id ) category_name, " +
            " C.name lottery_name," +
            "  abs(A.expense_score) expense_score," +
            "  A.status prize_status," +
            " A.order_no," +
            " A.update_time  " +
            "FROM " +
            " raffle_lottery_log A " +
            " LEFT JOIN member_user B ON A.user_id = B.id  " +
            " AND A.tenant_id = B.tenant_id " +
            " LEFT JOIN raffle_lottery C on A.lottery_id = C.id  " +
            " AND A.tenant_id = C.tenant_id " +
            " LEFT JOIN raffle_lottery_rule D ON A.rule_id = D.id  " +
            " AND A.tenant_id = D.tenant_id  " +
            " LEFT JOIN eb_goods_attr_value G ON D.sku_id = G.id and D.product_id = G.product_id  " +
            " AND  G.tenant_id = D.tenant_id  " +
            "<where>" +
            "<if test='userId != null '>" +
            " and A.user_id =  #{userId}  " +
            "</if>" +
            "<if test='lotteryId != null '>" +
            " and  A.lottery_id =  #{lotteryId}  " +
            "</if>" +
            "</where>" +
            " order by A.lottery_time desc " +
            "</script>"}
    )
    public IPage<AppUserLotteryLogRespVO> selectUserLotteryLogPageList(IPage<?> page, @Param("lotteryId")  Long lotteryId,@Param("userId")  Long userId);


    @Select({"<script>SELECT " +
            " A.id, " +
            " D.name prize_name,   " +
            " A.lottery_time,  A.user_id," +
            " B.nickname nick_name, " +
            " G.sku," +
            " D.avatar," +
            " D.category_id," +
            " ( SELECT S.label FROM system_dict_data S WHERE S.dict_type = 'su_goods_type' AND VALUE = D.category_id ) category_name, " +
            " C.name lottery_name," +
            "  abs(A.expense_score) expense_score," +
            "  A.status prize_status," +
            " A.order_no," +
            " A.update_time  " +
            "FROM " +
            " raffle_lottery_log A " +
            " LEFT JOIN member_user B ON A.user_id = B.id  " +
            " AND A.tenant_id = B.tenant_id " +
            " LEFT JOIN raffle_lottery C on A.lottery_id = C.id  " +
            " AND A.tenant_id = C.tenant_id " +
            " LEFT JOIN raffle_lottery_rule D ON A.rule_id = D.id  " +
            " AND A.tenant_id = D.tenant_id  " +
            " LEFT JOIN eb_goods_attr_value G ON D.sku_id = G.id and D.product_id = G.product_id  " +
            " AND  G.tenant_id = D.tenant_id  " +
            "<where>" +
            "<if test='userId != null '>" +
            " and A.user_id =  #{userId}  " +
            "</if>" +
            "<if test='lotteryId != null '>" +
            " and  A.lottery_id =  #{lotteryId}  " +
            "</if>" +
            "<if test='groupName != null '>" +
            " and  DATE_FORMAT( A.lottery_time, '%Y-%m' ) =  #{groupName}  " +
            "</if>" +
            "</where>" +
            " order by A.lottery_time desc " +
            "</script>"}
    )
    public List<AppUserLotteryLogRespVO> selectUserLotteryLogList(@Param("lotteryId")  Long lotteryId,@Param("userId")  Long userId,@Param("groupName")  String groupName);


    @Select({"<script>SELECT " +
            "  DATE_FORMAT( A.lottery_time, '%Y-%m' ) groupName " +
            "FROM " +
            " raffle_lottery_log A " +
            "<where>" +
            "<if test='userId != null '>" +
            " and A.user_id =  #{userId}  " +
            "</if>" +
            "<if test='lotteryId != null '>" +
            " and  A.lottery_id =  #{lotteryId}  " +
            "</if>" +
            "</where>" +
            " GROUP BY DATE_FORMAT( A.lottery_time, '%Y-%m' )  order by A.lottery_time desc " +
            "</script>"}
    )
    public IPage<AppYearMonthGroupUserLotteryLogRespVO> getYearMonthGroupLotteryLogList(IPage<?> page, @Param("lotteryId")  Long lotteryId, @Param("userId")  Long userId);




    @Select({"<script>SELECT " +
            " A.id, " +
            " D.name prize_name,   " +
            " B.nickname nick_name, " +
            " A.lottery_time," +
            " G.sku," +
            " D.avatar," +
            " D.category_id," +
            " ( SELECT S.label FROM system_dict_data S WHERE S.dict_type = 'su_goods_type' AND VALUE = D.category_id ) category_name " +
            "FROM " +
            " raffle_lottery_log A " +
            " LEFT JOIN member_user B ON A.user_id = B.id  " +
            " AND A.tenant_id = B.tenant_id " +
            " LEFT JOIN raffle_lottery C on A.lottery_id = C.id  " +
            " AND A.tenant_id = C.tenant_id " +
            " LEFT JOIN raffle_lottery_rule D ON A.rule_id = D.id  " +
            " AND A.tenant_id = D.tenant_id " +
            " LEFT JOIN eb_goods_attr_value G ON D.sku_id = G.id and D.product_id = G.product_id  " +
            " AND  G.tenant_id = D.tenant_id  " +
            "<where>" +
            "<if test='lotteryId != null '>" +
            " and  A.lottery_id =  #{lotteryId}  " +
            "</if>" +
            "<if test='userId != null '>" +
            " and A.user_id =  #{userId}  " +
            "</if>" +
            "</where>" +
            " order by A.lottery_time desc " +
            "</script>"}
    )
    public IPage<AppLotteryLogRespVO> selectAppLotteryLogPageList(IPage<?> page, @Param("lotteryId")  Long lotteryId, @Param("userId")  Long userId);


}